package com.gph.saviorframework.os.authz.token;

import com.gph.saviorframework.os.authz.OAuthHandler;
import com.gph.saviorframework.os.authz.OAuthTokenxRequest;
import com.gph.saviorframework.os.authz.validator.AbstractClientDetailsValidator;
import com.gph.saviorframework.os.authz.web.WebUtils;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class AbstractOAuthTokenHandler extends OAuthHandler implements OAuthTokenHandler {

    private static final Logger log = LoggerFactory.getLogger(AbstractOAuthTokenHandler.class);

    protected OAuthTokenxRequest tokenRequest;
    protected HttpServletResponse response;

    public final void handle(OAuthTokenxRequest tokenRequest, HttpServletResponse response) throws OAuthProblemException, OAuthSystemException {
        this.tokenRequest = tokenRequest;
        this.response = response;

        //validate
        if (validateFailed()) {
            return;
        }
        handleAfterValidation();
    }

    public HttpServletRequest getHttpServletRequest(){
        if(tokenRequest!=null){
            return tokenRequest.request();
        }
        return null;
    }

    protected boolean validateFailed() throws OAuthSystemException {
        AbstractClientDetailsValidator validator = getValidator();
        log.debug("Use [{}] validate client: {}", validator, tokenRequest.getClientId());

        final OAuthResponse oAuthResponse = validator.validate();
        return checkAndResponseValidateFailed(oAuthResponse);
    }

    protected boolean checkAndResponseValidateFailed(OAuthResponse oAuthResponse) {
        if (oAuthResponse != null) {
            log.debug("Validate OAuthAuthzRequest(client_id={}) failed", tokenRequest.getClientId());
            WebUtils.writeOAuthJsonResponse(response, oAuthResponse);
            return true;
        }
        return false;
    }

    protected abstract AbstractClientDetailsValidator getValidator();


    protected String clientId() {
        return tokenRequest.getClientId();
    }

    protected abstract void handleAfterValidation() throws OAuthProblemException, OAuthSystemException;
}
